package com.xthh._ble;

import android.app.Application;

import com.xt.pro.BLEControlJni;
import com.xt.pro.BLEDelegate;
import com.xthh.XTCore;
import com.xthh._enum.HH_EnumErrorCode;
import com.xthh._enum.HH_EnumFileType;
import com.xthh._enum.pic_storage.HH_EnumPicStorage_BrushType;
import com.xthh._enum.pic_storage.HH_EnumPicStorage_PicIndex;
import com.xthh._function.HH_CharUtil;
import com.xthh._function.HH_FileUtil;
import com.xthh._function.HH_SystemUtil;
import com.xthh._function.HH_TimeUtil;
import com.xthh._struct.HH_T_BindDevice;
import com.xthh._struct.HH_T_BleConnectResult;
import com.xthh._struct.HH_T_ScanResult;
import com.xthh._struct.HH_T_SystemParams;
import com.xthh.fastble.BleManager;
import com.xthh._function.HH_Logging;
import com.xthh.fastble.data.BleDevice;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

public class HH_BleCommunicator {
    static String TAG = "HH_BleCommunicator";
    static final int globa_n_SendBufferSizeBSCY = 1211;


    // 库的版本号
    final private static int LIB_VER = 25;

    public static int GetLibVer(){
        return LIB_VER;
    }

    // 蓝牙扫描
    public static ArrayList<HH_T_ScanResult> Scan(HH_T_SystemParams tp, String mac){
        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.SCAN_BEGIN.ordinal());
        HH_Logging.i(TAG, tp, "Scan");

        ArrayList<HH_T_ScanResult> listScanResult = new ArrayList<>();

        BleManager.getInstance().init(tp.getApplication());
        BleManager.getInstance()
                .enableLog(true)
                .setReConnectCount(1, 5000)
                .setConnectOverTime(20000)
                .setOperateTimeout(5000);
        if (!BleManager.getInstance().isBlueEnable()){
            HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_DISABLE.ordinal());
            return listScanResult;
        }

        // 让它堵着
        final CountDownLatch latch = new CountDownLatch(1);
        //String[] strWriteMac = new String[1];

        HH_BT.setScanRule();
        HH_BT.ScanBegin(tp, mac, new HH_BT.ResultCallBackScanResult() {
            @Override
            public void callback(HH_T_ScanResult state) {
                if (state == null){
                    latch.countDown();
                } else {
                    switch (state.getScanState()){
                        case FAIL:{
                            HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.SCAN_FAIL.ordinal());
                            latch.countDown();
                            break;
                        }
                        case FINISH:{
                            HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.SCAN_FINISH.ordinal());
                            latch.countDown();
                            break;
                        }
                        case SCANNING:{
                            HH_T_BindDevice tbd = state.getBindDevice();
                            if (tbd != null){
                                listScanResult.add(state);
                                HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, tbd, 0, HH_EnumErrorCode.SCAN_INFO.ordinal());
                            }
                            break;
                        }
                    }
                }
            }
        });

        try {
            latch.await();
        } catch (InterruptedException e) {
        }

/*        HH_Logging.i(TAG, tp, ctx, "完成了");
        for (int i = 0; i < listScanResult.size(); i++){
            HH_Logging.i(TAG, tp, ctx, "%d(%d)=%s", i, listScanResult.size(), listScanResult.get(i).getBindDevice().getMacRes());
        }*/

        return listScanResult;
    }

    public static String GetHardVersion(HH_T_SystemParams systemParams, String mac) {
        ArrayList<HH_T_ScanResult> list = HH_BleCommunicator.Scan(systemParams, mac);
        if (list != null) {
            if (list.size() == 1) {
                if (list.get(0).getBindDevice() != null) {
                    if (list.get(0).getBindDevice().getVer() != null) {
                        return list.get(0).getBindDevice().getVer();
                    }
                }
            }
        }
        return "";
    }


    // 蓝牙连接
    public static BleDevice Connect(HH_T_SystemParams tp, String mac){

        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_BEGIN_CONNECT.ordinal());
        HH_Logging.i(TAG, tp, "Connect");

        BleManager.getInstance().init(tp.getApplication());
        BleManager.getInstance()
                .enableLog(true)
                .setReConnectCount(1, 5000)
                .setConnectOverTime(20000)
                .setOperateTimeout(5000);
        if (!BleManager.getInstance().isBlueEnable()){
            HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_DISABLE.ordinal());
            return null;
        }

        // 让它堵着
        final CountDownLatch latch = new CountDownLatch(1);
        final BleDevice[] connectBle = new BleDevice[1];
        HH_BT.connectBle(tp, mac, new HH_BT.ResultCallBackConnectResult() {
            @Override
            public void callback(HH_T_BleConnectResult bleConnectResult) {
                connectBle[0] = bleConnectResult.getBle();
                latch.countDown();
            }
        });

        try {
            latch.await();
        } catch (InterruptedException e) {
        }


        return connectBle[0];
    }

    public static HH_EnumErrorCode SendDataToDevice(HH_T_SystemParams tp, BLE ble, byte[] order) {
        HH_Logging.i(TAG, tp, "SendDataToDevice:%s", HH_CharUtil.ByteToHexStr(order));
        int result = HH_BT.writeBle(tp, ble, order);

        if (result == 1)
            return HH_EnumErrorCode.SUCCESS;
        else if (result == 4)
            return HH_EnumErrorCode.BLE_IDENTITY_FAIL;
        else
            return HH_EnumErrorCode.FAIL;

    }

    public static HH_EnumErrorCode BrushPic(HH_T_SystemParams tp,
                                            String mac,
                                            List<Integer> data,
                                            int pageIntervalTime,
                                            boolean useBrushOrder,
                                            String deviceIdentity,
                                            int brushDelayTime,
                                            int epdParams){

        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_BRUSH_BEGIN.ordinal());

        String jniLogPath = HH_SystemUtil.GetTempPath(tp,0, HH_EnumFileType.JNI);
        HH_FileUtil.WriteFile(tp.getCtx(), jniLogPath, "LoadBleJNI", true);

        BLEDelegate delegateLight = new BLEDelegate();
        BLEControlJni.init(delegateLight,
                HH_CharUtil.StringToByte2(jniLogPath, "GB2312"),
                jniLogPath.length());

        // 连接
        long lTimeConnect = HH_TimeUtil.MadeMillisTimeMS();
        BleDevice device = HH_BleCommunicator.Connect(tp, mac);
        if (device == null){
            HH_Logging.i(TAG, tp, "连接失败");
            HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_CONNECT_FAIL.ordinal());
            return HH_EnumErrorCode.BLE_CONNECT_FAIL;
        }
        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", (int)(HH_TimeUtil.MadeMillisTimeMS() - lTimeConnect), HH_EnumErrorCode.TIME_CONSUME_BLE_CONNECT.ordinal());

        // 获取特征等信息  默认500，易葵测试改为1000
        HH_SystemUtil.Sleep(500);  // 需要等下，否则通知会开始失败
        BLE ble = new BLE(tp, device);
        if (!ble.IsGetCharacteristicResult()){
            HH_Logging.i(TAG, tp, "特征信息获取失败 断开连接");
            BleManager.getInstance().disconnectAllDevice();
            HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_CHARACTERISTIC_FAIL.ordinal());
            return HH_EnumErrorCode.BLE_CHARACTERISTIC_FAIL;
        } else {
            HH_Logging.i(TAG, tp, "读通知已开启");
        }

        // 发送删除指令
        HH_EnumErrorCode resultErrorCode = HH_BleCommunicator.SendDataToDevice(tp,
                ble,
                BLEControlJni.GetDelFlashOrderIdentity(data.size(), MadeEncryptedInfo(deviceIdentity, mac), 16));

        if (resultErrorCode == HH_EnumErrorCode.SUCCESS){
            HH_Logging.i(TAG, tp,  "清空缓存成功");
        } else if (resultErrorCode == HH_EnumErrorCode.BLE_IDENTITY_FAIL){
            return HH_EnumErrorCode.BLE_IDENTITY_FAIL;
        } else {
            HH_Logging.i(TAG, tp,  "清空缓存失败");
            BleManager.getInstance().disconnectAllDevice();
            HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.CLEAR_CACHE_FAIL.ordinal());
            return HH_EnumErrorCode.CLEAR_CACHE_FAIL;
        }

        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_BRUSH_DATA_SEND.ordinal());
        HH_Logging.i(TAG, tp, "发送图片数据");

        long lTimeSendData = HH_TimeUtil.MadeMillisTimeMS();
        resultErrorCode = HH_BleCommunicator.SendPicData(tp, ble, data, pageIntervalTime, false, null, 0, epdParams);
        HH_Logging.i(TAG, tp, "%s", resultErrorCode == HH_EnumErrorCode.SUCCESS ? "指令发送成功" : "指令发送失败");
        if (resultErrorCode == HH_EnumErrorCode.SUCCESS){
            // 数据发送用时
            HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", (int)(HH_TimeUtil.MadeMillisTimeMS() - lTimeSendData), HH_EnumErrorCode.TIME_CONSUME_DATA_SEND.ordinal());
        }

        if (useBrushOrder){
            if (resultErrorCode == HH_EnumErrorCode.SUCCESS){

                // 250811 添加个充会电的时间，康洁添加
                if (brushDelayTime > 1){
                    HH_SystemUtil.Sleep(brushDelayTime);
                }

                // 发送刷图指令
                HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_BRUSH_ING.ordinal());
                long lTimeBrush = HH_TimeUtil.MadeMillisTimeMS();
                resultErrorCode = HH_BleCommunicator.SendDataToDevice(tp,
                        ble,
                        BLEControlJni.GetUpdateOrderIdentity(4, 0, MadeEncryptedInfo(deviceIdentity, mac), 16));
                HH_Logging.i(TAG, tp, "%s", resultErrorCode == HH_EnumErrorCode.SUCCESS ? "刷图成功" : "刷图失败");
                if (resultErrorCode == HH_EnumErrorCode.SUCCESS){
                    HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", (int)(HH_TimeUtil.MadeMillisTimeMS() - lTimeBrush), HH_EnumErrorCode.TIME_CONSUME_BRUSH.ordinal());
                }


                // 修改为刷图失败
                if (resultErrorCode == HH_EnumErrorCode.FAIL)
                    resultErrorCode = HH_EnumErrorCode.BRUSH_FAIL;
            }
        }

        // 强制发送断电
        ble.Write(BLEControlJni.GetNfcOffOrderIdentity(MadeEncryptedInfo(deviceIdentity, mac), 16));

        // 断开连接
        BleManager.getInstance().disconnectAllDevice();

        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, resultErrorCode.ordinal());
        return resultErrorCode;
    }



    public static HH_EnumErrorCode BrushPrism(HH_T_SystemParams tp,
                                            String mac,
                                            List<Integer> data,
                                            int pageIntervalTime,
                                            boolean useBrushOrder,
                                            String deviceIdentity,
                                            int brushDelayTime, byte []prismParams, int prismParamsLen){

        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_BRUSH_BEGIN.ordinal());

        String jniLogPath = HH_SystemUtil.GetTempPath(tp,0, HH_EnumFileType.JNI);
        HH_FileUtil.WriteFile(tp.getCtx(), jniLogPath, "LoadBleJNI", true);

        BLEDelegate delegateLight = new BLEDelegate();
        BLEControlJni.init(delegateLight,
                HH_CharUtil.StringToByte2(jniLogPath, "GB2312"),
                jniLogPath.length());

        // 连接
        long lTimeConnect = HH_TimeUtil.MadeMillisTimeMS();
        BleDevice device = HH_BleCommunicator.Connect(tp, mac);
        if (device == null){
            HH_Logging.i(TAG, tp, "连接失败");
            HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_CONNECT_FAIL.ordinal());
            return HH_EnumErrorCode.BLE_CONNECT_FAIL;
        }
        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", (int)(HH_TimeUtil.MadeMillisTimeMS() - lTimeConnect), HH_EnumErrorCode.TIME_CONSUME_BLE_CONNECT.ordinal());

        // 获取特征等信息  默认500，易葵测试改为1000
        HH_SystemUtil.Sleep(500);  // 需要等下，否则通知会开始失败
        BLE ble = new BLE(tp, device);
        if (!ble.IsGetCharacteristicResult()){
            HH_Logging.i(TAG, tp, "特征信息获取失败 断开连接");
            BleManager.getInstance().disconnectAllDevice();
            HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_CHARACTERISTIC_FAIL.ordinal());
            return HH_EnumErrorCode.BLE_CHARACTERISTIC_FAIL;
        } else {
            HH_Logging.i(TAG, tp, "读通知已开启");
        }

        HH_EnumErrorCode resultErrorCode = HH_EnumErrorCode.FAIL;

        if (data == null || data.size() <= 0){
            byte[] order = null;
            order = BLEControlJni.GetPicUpdateOrderWithParams2(prismParams, prismParamsLen);
            HH_Logging.i(TAG, tp, "发送连接指令:" + HH_CharUtil.ByteToHexStr(order));
            resultErrorCode = HH_BleCommunicator.SendDataToDevice(tp, ble, order);
            // 这里需要等它返回
            if (resultErrorCode == HH_EnumErrorCode.SUCCESS) {
                HH_Logging.i(TAG, tp, "order-send-success");
            } else {
                HH_Logging.i(TAG, tp, "order-send-fail");
            }
        } else {
            // 发送删除指令
            resultErrorCode = HH_BleCommunicator.SendDataToDevice(tp,
                    ble,
                    BLEControlJni.GetDelFlashOrderIdentity(data.size(), MadeEncryptedInfo(deviceIdentity, mac), 16));

            if (resultErrorCode == HH_EnumErrorCode.SUCCESS){
                HH_Logging.i(TAG, tp,  "清空缓存成功");
            } else if (resultErrorCode == HH_EnumErrorCode.BLE_IDENTITY_FAIL){
                return HH_EnumErrorCode.BLE_IDENTITY_FAIL;
            } else {
                HH_Logging.i(TAG, tp,  "清空缓存失败");
                BleManager.getInstance().disconnectAllDevice();
                HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.CLEAR_CACHE_FAIL.ordinal());
                return HH_EnumErrorCode.CLEAR_CACHE_FAIL;
            }

            HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_BRUSH_DATA_SEND.ordinal());
            HH_Logging.i(TAG, tp, "发送图片数据");

            long lTimeSendData = HH_TimeUtil.MadeMillisTimeMS();
            resultErrorCode = HH_BleCommunicator.SendPicData(tp, ble, data, pageIntervalTime, true, prismParams, prismParamsLen, -2);
            HH_Logging.i(TAG, tp, "%s", resultErrorCode == HH_EnumErrorCode.SUCCESS ? "指令发送成功" : "指令发送失败");
            if (resultErrorCode == HH_EnumErrorCode.SUCCESS){
                // 数据发送用时
                HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", (int)(HH_TimeUtil.MadeMillisTimeMS() - lTimeSendData), HH_EnumErrorCode.TIME_CONSUME_DATA_SEND.ordinal());
            }




            if (useBrushOrder){
                if (resultErrorCode == HH_EnumErrorCode.SUCCESS){

                    // 250811 添加个充会电的时间，康洁添加
                    if (brushDelayTime > 1){
                        HH_SystemUtil.Sleep(brushDelayTime);
                    }

                    // 发送刷图指令
                    HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_BRUSH_ING.ordinal());
                    long lTimeBrush = HH_TimeUtil.MadeMillisTimeMS();
                    resultErrorCode = HH_BleCommunicator.SendDataToDevice(tp,
                            ble,
                            BLEControlJni.GetUpdateOrderIdentity(4, 0, MadeEncryptedInfo(deviceIdentity, mac), 16));
                    HH_Logging.i(TAG, tp, "%s", resultErrorCode == HH_EnumErrorCode.SUCCESS ? "刷图成功" : "刷图失败");
                    if (resultErrorCode == HH_EnumErrorCode.SUCCESS){
                        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", (int)(HH_TimeUtil.MadeMillisTimeMS() - lTimeBrush), HH_EnumErrorCode.TIME_CONSUME_BRUSH.ordinal());
                    }


                    // 修改为刷图失败
                    if (resultErrorCode == HH_EnumErrorCode.FAIL)
                        resultErrorCode = HH_EnumErrorCode.BRUSH_FAIL;
                }
            }
        }



        // 强制发送断电
        //ble.Write(BLEControlJni.GetNfcOffOrderIdentity(MadeEncryptedInfo(deviceIdentity, mac), 16));

        // 断开连接
        BleManager.getInstance().disconnectAllDevice();

        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, resultErrorCode.ordinal());
        return resultErrorCode;
    }

    private static HH_EnumErrorCode SendPicData(HH_T_SystemParams tp, BLE ble, List<Integer> data, int pageIntervalTime, boolean isPrism, byte []prismParams, int prismParamsLen, int epdParams) {
        List<List<Integer>> list = HH_SystemUtil.splitList(data, globa_n_SendBufferSizeBSCY);
        return HH_BT.sendDataInfo(tp, ble, list, 0, pageIntervalTime, isPrism, prismParams, prismParamsLen, epdParams);
    }
    private static HH_EnumErrorCode SendOTAData(HH_T_SystemParams tp, BLE ble, List<Integer> data, int pageIntervalTime) {
        List<List<Integer>> list = HH_SystemUtil.splitList(data, globa_n_SendBufferSizeBSCY);
        return HH_BT.sendDataInfo(tp, ble, list, 2, pageIntervalTime, false, null, 0, -2);
    }

    public static HH_EnumErrorCode NFCClose(HH_T_SystemParams tp, String mac, String deviceIdentity) {

        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_NFC_CLOSE_BEGIN.ordinal());

        String jniLogPath = HH_SystemUtil.GetTempPath(tp, 0, HH_EnumFileType.JNI);
        HH_FileUtil.WriteFile(tp.getCtx(), jniLogPath, "LoadBleJNI", true);

        BLEDelegate delegateLight = new BLEDelegate();
        BLEControlJni.init(delegateLight,
                HH_CharUtil.StringToByte2(jniLogPath, "GB2312"),
                jniLogPath.length());

        // 连接
        BleDevice device = HH_BleCommunicator.Connect(tp, mac);
        if (device == null){
            HH_Logging.i(TAG, tp, "连接失败");
            return HH_EnumErrorCode.BLE_CONNECT_FAIL;
        }

        // 获取特征等信息
        HH_SystemUtil.Sleep(500);  // 需要等下，否则通知会开始失败
        BLE ble = new BLE(tp, device);
        if (!ble.IsGetCharacteristicResult()){
            HH_Logging.i(TAG, tp, "特征信息获取失败 断开连接");
            BleManager.getInstance().disconnectAllDevice();
            return HH_EnumErrorCode.BLE_CHARACTERISTIC_FAIL;
        } else {
            HH_Logging.i(TAG, tp, "读通知已开启");
        }

        // 发送NFC断电指令
        HH_EnumErrorCode result = HH_BleCommunicator.SendDataToDevice(tp,
                ble,
                BLEControlJni.GetNfcOffOrderIdentity(MadeEncryptedInfo(deviceIdentity, mac), 16));

        HH_Logging.i(TAG, tp, "%s", result == HH_EnumErrorCode.SUCCESS ? "发送NFC断电指令成功" : "发送NFC断电指令失败");

        // 断开连接
        BleManager.getInstance().disconnectAllDevice();

        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, result.ordinal());
        return result;
    }


    public static HH_EnumErrorCode LedControl(HH_T_SystemParams tp, String mac, String deviceIdentity, int colorType, int color, int duration) {

        //HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_NFC_CLOSE_BEGIN.ordinal());

        String jniLogPath = HH_SystemUtil.GetTempPath(tp, 0, HH_EnumFileType.JNI);
        HH_FileUtil.WriteFile(tp.getCtx(), jniLogPath, "LoadBleJNI", true);

        BLEDelegate delegateLight = new BLEDelegate();
        BLEControlJni.init(delegateLight,
                HH_CharUtil.StringToByte2(jniLogPath, "GB2312"),
                jniLogPath.length());

        // 连接
        BleDevice device = HH_BleCommunicator.Connect(tp, mac);
        if (device == null){
            HH_Logging.i(TAG, tp, "连接失败");
            return HH_EnumErrorCode.BLE_CONNECT_FAIL;
        }

        // 获取特征等信息
        HH_SystemUtil.Sleep(500);  // 需要等下，否则通知会开始失败
        BLE ble = new BLE(tp, device);
        if (!ble.IsGetCharacteristicResult()){
            HH_Logging.i(TAG, tp, "特征信息获取失败 断开连接");
            BleManager.getInstance().disconnectAllDevice();
            return HH_EnumErrorCode.BLE_CHARACTERISTIC_FAIL;
        } else {
            HH_Logging.i(TAG, tp, "读通知已开启");
        }

        // 发送灯控指令
        HH_EnumErrorCode result = HH_BleCommunicator.SendDataToDevice(tp,
                ble,
                BLEControlJni.GetLEDOrder(colorType, color, duration));

        HH_Logging.i(TAG, tp, "%s", result == HH_EnumErrorCode.SUCCESS ? "灯控成功" : "灯控失败");

        // 断开连接
        BleManager.getInstance().disconnectAllDevice();

        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, result.ordinal());
        return result;
    }


    public static HH_EnumErrorCode NFCUnLock(HH_T_SystemParams tp, String mac, String deviceIdentity) {

        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_NFC_UNLOCK_BEGIN.ordinal());

        String jniLogPath = HH_SystemUtil.GetTempPath(tp, 0, HH_EnumFileType.JNI);
        HH_FileUtil.WriteFile(tp.getCtx(), jniLogPath, "LoadBleJNI", true);

        BLEDelegate delegateLight = new BLEDelegate();
        BLEControlJni.init(delegateLight,
                HH_CharUtil.StringToByte2(jniLogPath, "GB2312"),
                jniLogPath.length());

        // 连接
        BleDevice device = HH_BleCommunicator.Connect(tp, mac);
        if (device == null){
            HH_Logging.i(TAG, tp, "连接失败");
            return HH_EnumErrorCode.BLE_CONNECT_FAIL;
        }

        // 获取特征等信息
        HH_SystemUtil.Sleep(1000);  // 需要等下，否则通知会开始失败
        BLE ble = new BLE(tp, device);
        if (!ble.IsGetCharacteristicResult()){
            HH_Logging.i(TAG, tp, "特征信息获取失败 断开连接");
            BleManager.getInstance().disconnectAllDevice();
            return HH_EnumErrorCode.BLE_CHARACTERISTIC_FAIL;
        } else {
            HH_Logging.i(TAG, tp, "读通知已开启");
        }

        // 发送NFC断电指令
        HH_EnumErrorCode result = HH_BleCommunicator.SendDataToDevice(tp,
                ble,
                BLEControlJni.GetNfcUnLockIdentity(MadeEncryptedInfo(deviceIdentity, mac), 16));

        HH_Logging.i(TAG, tp, "%s", result == HH_EnumErrorCode.SUCCESS ? "发送NFC解锁指令成功" : "发送NFC解锁指令失败");

        // 断开连接
        BleManager.getInstance().disconnectAllDevice();

        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, result.ordinal());
        return result;
    }

    public static byte []MadeEncryptedInfo(String strDeviceIdentity, String strMac){
        final int  dataLen = 16;
        if (strDeviceIdentity == null || strDeviceIdentity.length() != 10)
            return new byte[dataLen];

        if (strMac == null || strMac.length() != 12)
            return new byte[dataLen];



        byte [] info = new byte[dataLen];
        byte [] identity = HH_CharUtil.StrToByteArray(strDeviceIdentity);
        byte [] mac = HH_CharUtil.GetMacFormStr2(strMac);

        if (identity != null && identity.length == 10){
            if (mac != null && mac.length == 6){
                for (int i = 0; i < 10; i++)
                    info[i] = identity[i];

                for (int i = 0; i < 6; i++)
                    info[i + 10] = mac[i];

                if (info == null || info.length != dataLen){
                    return new byte[dataLen];
                }

                return info;
            }
        }

        return new byte[dataLen];
    }

    public static HH_EnumErrorCode OTA(HH_T_SystemParams tp, String mac, String path, int pageIntervalTime, String deviceIdentity) {

        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_OTA_BEGIN.ordinal());

        byte[] bContent = HH_FileUtil.ReadFileB(tp.getCtx(), path);
        if (bContent.length <= 0) {
            return HH_EnumErrorCode.DATA_FAIL;
        }

        String jniLogPath = HH_SystemUtil.GetTempPath(tp, 0, HH_EnumFileType.JNI);
        HH_FileUtil.WriteFile(tp.getCtx(), jniLogPath, "LoadBleJNI", true);

        BLEDelegate delegateLight = new BLEDelegate();
        BLEControlJni.init(delegateLight,
                HH_CharUtil.StringToByte2(jniLogPath, "GB2312"),
                jniLogPath.length());

        // 连接
        BleDevice device = HH_BleCommunicator.Connect(tp, mac);
        if (device == null){
            HH_Logging.i(TAG, tp, "连接失败");
            return HH_EnumErrorCode.BLE_CONNECT_FAIL;
        }

        // 获取特征等信息
        HH_SystemUtil.Sleep(500);  // 需要等下，否则通知会开始失败
        BLE ble = new BLE(tp, device);
        if (!ble.IsGetCharacteristicResult()){
            HH_Logging.i(TAG, tp, "特征信息获取失败 断开连接");
            BleManager.getInstance().disconnectAllDevice();
            return HH_EnumErrorCode.BLE_CHARACTERISTIC_FAIL;
        } else {
            HH_Logging.i(TAG, tp, "读通知已开启");
        }


        List<Integer> list81 = new ArrayList<Integer>();
        for (int i = 0; i < bContent.length; i++) {
            Integer bt = Integer.valueOf(bContent[i] & 0xFF);
            list81.add(bt);
        }

        byte[] fileName = new byte[12];
        fileName[0] = bContent[8];
        fileName[1] = bContent[9];
        fileName[2] = bContent[10];
        fileName[3] = bContent[11];


        HH_EnumErrorCode result = HH_BleCommunicator.SendDataToDevice(tp,
                ble,
                BLEControlJni.GetDelFlashOrderIdentity(list81.size(), MadeEncryptedInfo(deviceIdentity, mac), 16));
        if (result == HH_EnumErrorCode.FAIL){
            HH_Logging.i(TAG, tp, "清空缓存失败");
            BleManager.getInstance().disconnectAllDevice();
            return HH_EnumErrorCode.CLEAR_CACHE_FAIL;
        } else if (result == HH_EnumErrorCode.BLE_IDENTITY_FAIL){
            HH_Logging.i(TAG, tp, "身份验证失败");
            BleManager.getInstance().disconnectAllDevice();
            return HH_EnumErrorCode.BLE_IDENTITY_FAIL;
        }

        HH_Logging.i(TAG, tp, "发送OTA数据");
        result = HH_BleCommunicator.SendOTAData(tp, ble, list81, pageIntervalTime);

        // 断开连接
        BleManager.getInstance().disconnectAllDevice();

        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, result.ordinal());
        return result;
    }

    // 身份加密
    public static HH_EnumErrorCode IdentityEncryption(HH_T_SystemParams tp, String mac, String identity, boolean open) {
        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_IDENTITY_ENCRYPTION_BEGIN.ordinal());

        if (identity == null) {
            return HH_EnumErrorCode.DATA_FAIL;
        }

        if (identity.length() == 0 || identity.length() == 10){

        } else {
            return HH_EnumErrorCode.DATA_FAIL;
        }

        String jniLogPath = HH_SystemUtil.GetTempPath(tp, 0, HH_EnumFileType.JNI);
        HH_FileUtil.WriteFile(tp.getCtx(), jniLogPath, "LoadBleJNI", true);

        BLEDelegate delegateLight = new BLEDelegate();
        BLEControlJni.init(delegateLight,
                HH_CharUtil.StringToByte2(jniLogPath, "GB2312"),
                jniLogPath.length());

        // 连接
        BleDevice device = HH_BleCommunicator.Connect(tp,  mac);
        if (device == null){
            HH_Logging.i(TAG, tp, "连接失败");
            return HH_EnumErrorCode.BLE_CONNECT_FAIL;
        }

        // 获取特征等信息
        HH_SystemUtil.Sleep(500);  // 需要等下，否则通知会开始失败
        BLE ble = new BLE(tp, device);
        if (!ble.IsGetCharacteristicResult()){
            HH_Logging.i(TAG, tp, "特征信息获取失败 断开连接");
            BleManager.getInstance().disconnectAllDevice();
            return HH_EnumErrorCode.BLE_CHARACTERISTIC_FAIL;
        } else {
            HH_Logging.i(TAG, tp, "读通知已开启");
        }

        HH_EnumErrorCode result = HH_BleCommunicator.SendDataToDevice(tp,
                ble,
                BLEControlJni.GetSafeModeOrder(open?2:1, MadeEncryptedInfo(identity, mac), 16));
        if (result == HH_EnumErrorCode.SUCCESS){

        } else if (result == HH_EnumErrorCode.BLE_IDENTITY_FAIL){
            HH_Logging.i(TAG, tp, "认证失败");
            BleManager.getInstance().disconnectAllDevice();
            return HH_EnumErrorCode.BLE_IDENTITY_FAIL;
        } else {
            HH_Logging.i(TAG, tp, "身份认证失败");
            BleManager.getInstance().disconnectAllDevice();
            return HH_EnumErrorCode.BLE_IDENTITY_ENCRYPTION_FAIL;
        }

        HH_Logging.i(TAG, tp, "%s", result == HH_EnumErrorCode.SUCCESS ? "成功" : "失败");

        // 断开连接
        BleManager.getInstance().disconnectAllDevice();

        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, result.ordinal());
        return result;
    }

    public static void StopBrushPic() {
        BleManager.getInstance().disconnectAllDevice();
    }

    public static boolean isBlueEnable(Application api) {
        BleManager.getInstance().init(api);
        BleManager.getInstance()
                .enableLog(true)
                .setReConnectCount(1, 5000)
                .setConnectOverTime(20000)
                .setOperateTimeout(5000);
        return BleManager.getInstance().isBlueEnable();
    }

    public static void StopScan() {
        BleManager.getInstance().cancelScan();
    }

    public static void Scan2(HH_T_SystemParams tp, String mac) {
        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.SCAN_BEGIN.ordinal());
        HH_Logging.i(TAG, tp, "Scan");

        ArrayList<HH_T_ScanResult> listScanResult = new ArrayList<HH_T_ScanResult>();

        BleManager.getInstance().init(tp.getApplication());
        BleManager.getInstance()
                .enableLog(true)
                .setReConnectCount(1, 5000)
                .setConnectOverTime(20000)
                .setOperateTimeout(5000);
        if (!BleManager.getInstance().isBlueEnable()){
            HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_DISABLE.ordinal());
            return;
        }

        HH_BT.setScanRule();
        HH_BT.ScanBegin(tp, mac, new HH_BT.ResultCallBackScanResult() {
            @Override
            public void callback(HH_T_ScanResult state) {
                if (state == null){

                } else {
                    switch (state.getScanState()){
                        case FAIL:{
                            HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.SCAN_FAIL.ordinal());
                            break;
                        }
                        case FINISH:{
                            HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.SCAN_FINISH.ordinal());
                            break;
                        }
                        case SCANNING:{
                            HH_T_BindDevice tbd = state.getBindDevice();
                            if (tbd != null){
                                listScanResult.add(state);
                                HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, tbd, 0, HH_EnumErrorCode.SCAN_INFO.ordinal());
                            }
                            break;
                        }
                    }
                }
            }
        });
    }

    // 图片存储
    public static HH_EnumErrorCode ImageStorage(HH_T_SystemParams tp,
                                                String mac,
                                                List<Integer> data,
                                                int pageIntervalTime,
                                                String deviceIdentity,
                                                HH_EnumPicStorage_PicIndex picIndex,
                                                HH_EnumPicStorage_BrushType brushType,
                                                int intervalTime,
                                                int []delIndex) {

        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_BRUSH_BEGIN.ordinal());

        String jniLogPath = HH_SystemUtil.GetTempPath(tp,0, HH_EnumFileType.JNI);
        HH_FileUtil.WriteFile(tp.getCtx(), jniLogPath, "LoadBleJNI", true);

        BLEDelegate delegateLight = new BLEDelegate();
        BLEControlJni.init(delegateLight,
                HH_CharUtil.StringToByte2(jniLogPath, "GB2312"),
                jniLogPath.length());

        // 连接
        long lTimeConnect = HH_TimeUtil.MadeMillisTimeMS();
        BleDevice device = HH_BleCommunicator.Connect(tp, mac);
        if (device == null){
            HH_Logging.i(TAG, tp, "连接失败");
            HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_CONNECT_FAIL.ordinal());
            return HH_EnumErrorCode.BLE_CONNECT_FAIL;
        }
        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", (int)(HH_TimeUtil.MadeMillisTimeMS() - lTimeConnect), HH_EnumErrorCode.TIME_CONSUME_BLE_CONNECT.ordinal());

        // 获取特征等信息  默认500，易葵测试改为1000
        HH_SystemUtil.Sleep(500);  // 需要等下，否则通知会开始失败
        BLE ble = new BLE(tp, device);
        if (!ble.IsGetCharacteristicResult()){
            HH_Logging.i(TAG, tp, "特征信息获取失败 断开连接");
            BleManager.getInstance().disconnectAllDevice();
            HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_CHARACTERISTIC_FAIL.ordinal());
            return HH_EnumErrorCode.BLE_CHARACTERISTIC_FAIL;
        } else {
            HH_Logging.i(TAG, tp, "读通知已开启");
        }

         //   * @param picIndex 图片序号，0-6，其中0表示删除所有图片，1-6表示图片序号
         //   * @param brushType 刷新类型，0表示保存并立即刷新，1表示保存但不刷新，2表示图片轮播（从图片1开始），3定时任务（暂无效），4表示删除当前序号的图片
         //   * @param intervalTime 轮播间隔时间（0-255），0表示停止轮播，其它表示轮播间隔时间，单位-分钟

        HH_EnumErrorCode resultErrorCode = HH_EnumErrorCode.BLE_CONNECT_SUCCESS;
        if (brushType == HH_EnumPicStorage_BrushType.SAVE_AND_BRUSH || brushType == HH_EnumPicStorage_BrushType.SAVE_NO_BRUSH){
            // 0表示保存并立即刷新，1表示保存但不刷新
            // 需要发图片数据
            byte []parameter = new byte[3];
            parameter[0] = 1; // 表示带参数
            parameter[1] = (byte)(picIndex.ordinal() & 0xff);  // 图片序号
            parameter[2] = (byte)(brushType.ordinal() & 0xff); // 刷新标志

            HH_Logging.i(TAG, tp,  "同步任务：序号=%d,标志=%s", picIndex.ordinal(), brushType.toString());

            // 发送删除指令
            resultErrorCode = HH_BleCommunicator.SendDataToDevice(tp,
                    ble,
                    BLEControlJni.GetDelFlashOrderIdentity(data.size(), MadeEncryptedInfo(deviceIdentity, mac), 16));

            if (resultErrorCode == HH_EnumErrorCode.SUCCESS){
                HH_Logging.i(TAG, tp,  "清空缓存成功");
            } else if (resultErrorCode == HH_EnumErrorCode.BLE_IDENTITY_FAIL){
                return HH_EnumErrorCode.BLE_IDENTITY_FAIL;
            } else {
                HH_Logging.i(TAG, tp,  "清空缓存失败");
                BleManager.getInstance().disconnectAllDevice();
                HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.CLEAR_CACHE_FAIL.ordinal());
                return HH_EnumErrorCode.CLEAR_CACHE_FAIL;
            }

            HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_BRUSH_DATA_SEND.ordinal());
            HH_Logging.i(TAG, tp, "发送图片数据");

            long lTimeSendData = HH_TimeUtil.MadeMillisTimeMS();
            resultErrorCode = HH_BleCommunicator.SendPicData_imageStorage(tp, ble, data, pageIntervalTime, parameter);
            HH_Logging.i(TAG, tp, "%s", resultErrorCode == HH_EnumErrorCode.SUCCESS ? "指令发送成功" : "指令发送失败");
            if (resultErrorCode == HH_EnumErrorCode.SUCCESS){
                // 数据发送用时
                HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", (int)(HH_TimeUtil.MadeMillisTimeMS() - lTimeSendData), HH_EnumErrorCode.TIME_CONSUME_DATA_SEND.ordinal());
            }
        } else if (brushType == HH_EnumPicStorage_BrushType.LOOP_PLAY){
            if (intervalTime <= 255){
                //2 表示图片轮播（从图片1开始），4表示删除当前序号的图片
                byte []parameter = new byte[4];
                parameter[0] = 1; // 表示带参数
                parameter[1] = 1; //(byte)(picIndex.ordinal() & 0xff);  // 图片序号 固定从1开始
                parameter[2] = (byte)(brushType.ordinal() & 0xff); // 刷新标志
                parameter[3] = (byte)(intervalTime & 0xff); // 参数 暂时为1字节的图片轮播的间隔时间

                HH_Logging.i(TAG, tp,  "轮播任务：序号=%d,标志=%s,间隔时间=%d", 1, brushType.toString(), intervalTime);
                resultErrorCode = HH_BT.sendDataInfo_imageOrder(tp, ble, parameter);
            } else {
                HH_Logging.i(TAG, tp,  "待定待定");
                // 待定，轮播是针对所有图片循环播放的，定时是针对每一张图片定时播放的
                // 时间太长，改为定时任务
               /* byte []parameter = new byte[5];
                parameter[0] = 1; // 表示带参数
                parameter[1] = 1; //(byte)(picIndex.ordinal() & 0xff);  // 图片序号 固定从1开始
                parameter[2] = (byte)(brushType.ordinal() & 0xff); // 刷新标志
                parameter[3] = (byte)(intervalTime & 0xff); // 参数 暂时为1字节的图片轮播的间隔时间

                HH_Logging.i(TAG, tp,  "轮播任务：序号=%d,标志=%s,间隔时间=%d", 1, brushType.toString(), intervalTime);
                resultErrorCode = HH_BT.sendDataInfo_imageOrder(tp, ble, parameter);*/
            }

        } else if (brushType == HH_EnumPicStorage_BrushType.DEL){

            if (delIndex == null || delIndex.length <= 0){
                // del all
                byte []parameter = new byte[3];
                parameter[0] = 1; // 表示带参数
                parameter[1] = 0;  // 图片序号
                parameter[2] = (byte)(brushType.ordinal() & 0xff); // 刷新标志
                HH_Logging.i(TAG, tp,  "删除所有任务：序号=%d,标志=%s", 0, brushType.toString());
                resultErrorCode = HH_BT.sendDataInfo_imageOrder(tp, ble, parameter);

            } else {
                for (int i = 0; i < delIndex.length; i++){
                    byte []parameter = new byte[3];
                    parameter[0] = 1; // 表示带参数
                    parameter[1] = (byte)(delIndex[i] & 0xff);  // 图片序号
                    parameter[2] = (byte)(brushType.ordinal() & 0xff); // 刷新标志
                    HH_Logging.i(TAG, tp,  "删除当前任务：序号=%d,标志=%s", 0, brushType.toString());
                    resultErrorCode = HH_BT.sendDataInfo_imageOrder(tp, ble, parameter);
                }
            }

        } else {
            // 无效
        }



              // 断开连接
        BleManager.getInstance().disconnectAllDevice();

        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, resultErrorCode.ordinal());
        return resultErrorCode;

    }

    private static HH_EnumErrorCode SendPicData_imageStorage(HH_T_SystemParams tp, BLE ble, List<Integer> data, int pageIntervalTime, byte[] parameter) {
        List<List<Integer>> list = HH_SystemUtil.splitList(data, globa_n_SendBufferSizeBSCY);
        return HH_BT.sendDataInfo_imageStorage(tp, ble, list, pageIntervalTime, parameter);
    }
}
